package com.aosan.website.auth.config

import com.aosan.website.auth.service.UserDetailsService
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer
import org.springframework.security.oauth2.provider.ClientDetailsService
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService
import org.springframework.security.oauth2.provider.token.TokenEnhancer
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore
import javax.sql.DataSource

@EnableAuthorizationServer
@Configuration
class AuthorizationServerConfiguration(
        val authenticationManager: AuthenticationManager,
        val dataSource: DataSource,
        val userDetailsService: UserDetailsService
) : AuthorizationServerConfigurerAdapter() {
    /**
     * 采取从数据库中读取Client配置
     *
     * @return ClientDetailsService
     */
    @Bean
    fun clientDetails(): ClientDetailsService = JdbcClientDetailsService(dataSource)


    @Throws(Exception::class)
    override fun configure(clients: ClientDetailsServiceConfigurer) {
        clients.withClientDetails(clientDetails())
    }

    @Throws(Exception::class)
    override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
        endpoints
                .authenticationManager(authenticationManager)
                .tokenStore(jwtTokenStore())
                .accessTokenConverter(accessTokenConverter())
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                .userDetailsService(userDetailsService)
        endpoints.clientDetailsService = clientDetails()

    }

    @Throws(Exception::class)
    override fun configure(security: AuthorizationServerSecurityConfigurer) {
        security.allowFormAuthenticationForClients()
                .checkTokenAccess("permitAll()")
    }

    @Bean
    fun jwtTokenStore(): JwtTokenStore = JwtTokenStore(accessTokenConverter())

    @Bean
    fun accessTokenConverter(): JwtAccessTokenConverter = JwtAccessTokenConverter().apply {
        setSigningKey("test-secret")
    }

    @Bean
    fun tokenEnhancer(): TokenEnhancer {
        return JwtTokenEnhancer()
    }


}